require 'thor'
require 'colorize'
require 'terminal-table'
require 'termarks/bookmark_manager'

module Termarks

  #
  # Main CLI class
  #
  class CLI < Thor

    default_task :list

    def initialize(*args)
        # loads the bookmarks from file.
        Termarks::BookmarkManager.load
        super
    end

    desc "add", "Adds a new bookmark"
    def add()

      say "Adding bookmark", :green

      begin

        identifier = ask format_prompt("Identifier (must be unique and contains only alphanumeric characters)")
        Termarks::BookmarkManager.validate_identifier identifier

        cmd = ask format_prompt("Command")

        description = ask format_prompt("Description")

        Termarks::BookmarkManager.add identifier, cmd, description
        say "Bookamrk added!", :green

      rescue => ex
        puts ex.to_s.colorize(:red)
      end

    end

    desc "delete IDENTIFIER", "Deletes a bookamrk with the specified identifier"
    def delete(identifier)

      if yes? "Are you sure you want to delete the bookmark '#{identifier}'?", :on_red
        begin
          Termarks::BookmarkManager.delete identifier
          say "Bookmark with identifier '#{identifier}' deleted.", :green
        rescue => ex
          puts ex.to_s.colorize(:red)
        end
      end

    end

    desc "list", "Lists all bookmarks"
    def list

        bookmarks = Termarks::BookmarkManager.get_bookmarks

        if bookmarks.length > 0
          table = Terminal::Table.new
          rows = []

          bookmarks.each do |identifier, value|
            rows << [
              identifier.colorize(:green),
              wrap_string(value['cmd'], 100).colorize(:yellow),
              wrap_string(value['description'], 60)
            ]
          end

          table.headings = ['identifier', 'command', 'description']
          table.rows = rows
          puts table

        else
          if yes? format_prompt("No bookmarks found! do you want to add a new bookmark?")
            add()
          end
        end
    end

    desc "version", "Displays the gem version"
    def version
      say "Termarks #{ Termarks::VERSION }"
    end

    no_commands do
      #
      # helper method to format a prompt
      # @param text [String] The text to format
      #
      def format_prompt text
        set_color text, :black ,:on_cyan
      end

      #
      # Helper function to wrap a string.
      # @param s [String] The text string
      # @param max [Integer] The max number of characters
      #
      def wrap_string(s, max)
        chars = []
        dist = 0
        s.chars.each do |c|
          chars << c
          dist += 1
          if c == "\n"
            dist = 0
          elsif dist == max
            dist = 0
            chars << "\n"
          end
        end
        chars = chars[0..-2] if chars.last == "\n"
        chars.join
      end
    end
  end
end
